package reflection;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

// 目标类：包含不同访问修饰符的属性
class Student {
    public String name; // 公共属性
    private int age;    // 私有属性
    protected String gender; // 受保护属性

    public Student(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Student{name='" + name + "', age=" + age + ", gender='" + gender + "'}";
    }
}

public class AccessFields {
    public static void main(String[] args) throws ClassNotFoundException,
            NoSuchMethodException, InvocationTargetException, InstantiationException,
            IllegalAccessException, NoSuchFieldException {

        // 1. 创建对象（反射方式）
        Class<?> studentClass = Class.forName("Student");
        Student student = (Student) studentClass.getConstructor(String.class, int.class, String.class)
                .newInstance("张三", 18, "男");
        System.out.println("原始对象：" + student);

        // 2. 访问公共属性
        Field nameField = studentClass.getField("name"); // getField只能获取公共属性
        String name = (String) nameField.get(student); // 读取属性值
        System.out.println("读取name：" + name);

        nameField.set(student, "李四"); // 修改属性值
        System.out.println("修改name后：" + student);

        // 3. 访问私有属性（需setAccessible(true)）
        Field ageField = studentClass.getDeclaredField("age"); // getDeclaredField获取所有属性
        ageField.setAccessible(true); // 关键：允许访问私有属性
        int age = (int) ageField.get(student);
        System.out.println("读取age：" + age);

        ageField.set(student, 20); // 修改私有属性值
        System.out.println("修改age后：" + student);

        // 4. 访问受保护属性
        Field genderField = studentClass.getDeclaredField("gender");
        genderField.setAccessible(true); // 受保护属性也需要取消检查
        genderField.set(student, "女");
        System.out.println("修改gender后：" + student);
    }
}
